/*
 * M.cpp
 *
 *  Created on: Nov 29, 2010
 *      Author: nobal
 */

#include "Commonfunction.h"
#include "Cserver.h"
#include "LServer.h"
#include "Client.h"

using namespace std;

void testmessage(){
	string msgString;
		string encodedString;
		Message msg;
		vector<string> v;
		bool success;
		/*
		 *(1)
		 * Message Type: Hello
		 * Objective:
		 * 		- Periodically Send by LS to CS to inform that it is still active.
		 * Example:- We don't use for the moment.
		 */

		/**
		 * (2)
		 * Message Type: Bye
		 * Used to inform CS that LS is going to be offline so that CS removes all entries
		 * corresponding to the LS from the chunk info table.
		 Example:
		 */
		// Create a message
		msgString = "Bye";
		MessageLS2CSBye byeMsg(LS_2_CS_BYE, msgString);
		// Get encoded string to send over network
		encodedString = byeMsg.encode();
		// Send encodedString over a network.
		// Once u receive at the destination, decode it.
		success = msg.decode(encodedString);
		if (success) {
			//process if it is a bye message
			if (msg.getMessageType() == LS_2_CS_BYE) {
				//print the message type
				cout << "MessageType2:" + msg.getMessageType() << endl;
				//print the message
				cout << "Actual Message2:" + msg.getMessage() << endl;
			}
		} else {
			cout << "Unable to decode the message..." << endl;
		}

		/**
		 * (3)
		 * Message Type: LS2LS
		 * Used to inform CS that LS is going to be offline so that CS removes all entries
		 * corresponding to the LS from the chunk info table.
		 Example:
		 */
		// Create a Message
		msgString = "file1.txt";
		MessageLS2LS ls2ls(LS_2_LS_GET_CHUNK, msgString);
		// Get encoded string to send over network
		encodedString = ls2ls.encode();
		// Send encodedString over a network.
		// Once u receive at the destination, decode it.
		success = msg.decode(encodedString);
		if (success) {
			//process if it is a bye message
			if (msg.getMessageType() == LS_2_LS_GET_CHUNK) {
				//print the message type
				cout << "MessageType3:" + msg.getMessageType() << endl;
				//print the message
				cout << "Actual Message3:" + msg.getMessage() << endl;
			}
		} else {
			cout << "Unable to decode the message..." << endl;
		}

		/**
		 * (4)
		 * Message Type: MSG_CHUNK_INFO_ADV
		 * Used to inform CS the available chunks in LS so that CS addes/updates the chunk info
		 *
		 * corresponding to the LS from the chunk info table.
		 Example:
		 */
		// Create a Message: Two options
		MessageChunkInfo ls2csChunkInfo(MSG_CHUNK_INFO_ADV);

		//For Option1
		v.clear();
		v.push_back("file1.txt");
		v.push_back("file2.txt");
		v.push_back("file3.txt");

		//For Option2
		msgString = MSG_CHUNK_INFO_ADV;
		msgString.append(MSG_SEPARATOR);
		msgString.append("file1.txt");
		msgString.append(MSG_SEPARATOR);
		msgString.append("file2.txt");
		msgString.append(MSG_SEPARATOR);
		msgString.append("file3.txt");

		//option2
		ls2csChunkInfo = MessageChunkInfo(MSG_CHUNK_INFO_ADV, msgString);

		//Option1
		ls2csChunkInfo = MessageChunkInfo(v, MSG_CHUNK_INFO_ADV);

		// Get encoded string to send over network
		encodedString = ls2csChunkInfo.encode();

		// Send encodedString over a network.
		// Once u receive at the destination, decode it.
		success = msg.decode(encodedString);
		if (success) {
			//process if it is a bye message
			if (msg.getMessageType() == MSG_CHUNK_INFO_ADV) {

				MessageChunkInfo ls2csChunkInfo1=MessageChunkInfo(MSG_CHUNK_INFO_ADV);
				ls2csChunkInfo1.setChunksFromRawMsg(encodedString);

				//print the message type
				cout << "MessageType4:" + ls2csChunkInfo1.getMessageType() << endl;
				//print the message
				cout << "Actual Message4:" + ls2csChunkInfo1.getMessage() << endl;

				//Access the chunks
				std::vector<string> chunks=ls2csChunkInfo1.getChunks();
				for(vector<string>::const_iterator it = chunks.begin(); it != chunks.end(); ++it){
					cout<<"Chunk: "<< *it<<endl;
				}

			}
		} else {
			cout << "Unable to decode the message..." << endl;
	}

	/**
	 * (5)
	 * Message Type: LS_2_CS_REQ
	 * Used to request CS for information of chunks of a file (A.txt)
	 *
	*/
		// Create a Message
		msgString = "A.txt";
		MessageLS2CSReq ls2csReq(LS_2_CS_REQ, msgString);
		// Get encoded string to send over network
		encodedString = ls2csReq.encode();
		// Send encodedString over a network.
		// Once u receive at the destination, decode it.
		success = msg.decode(encodedString);
		if (success) {
			//process if it is a bye message
			if (msg.getMessageType() == LS_2_CS_REQ) {
				//print the message type
				cout << "MessageType5:" + msg.getMessageType() << endl;
				//print the message
				cout << "Actual Message5:" + msg.getMessage() << endl;
			}
		} else {
			cout << "Unable to decode the message..." << endl;
		}

	/**
	 * (6)
	 * Message Type: CS_2_LS_REP
	 * Used by CS to send chunk information to LS  curresponding to the request a file (A.txt in example 5 just above this)
	 * Example:
	 * 	 This is same as (4). Just replace MSG_CHUNK_INFO_ADV by CS_2_LS_REP
	*/


}

void menu()
{
	cout << "Please choose the type of service you wanna boot up" << endl;
	cout << "1. Central Server" << endl;
	cout << "2. Local Server" << endl;
	cout << "3. Client" << endl;
	cout << "4. Test nodes"<<endl;
	cout << "==================" << endl;
}

void CS()
{
	Cserver cs(PROTOPORT);
}

void LS()
{
	LServer testls;

}

void CLT()
{
    Client testcl;
}



int main() {

	menu();
	int n;
	cin >> n;
	switch(n){
	case 1:
		CS();
		break;
	case 2:
		LS();
        break;
	case 3:
        CLT();
        break;


	default:

		exit(0);
	}
	return 0;
}
